using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Http;
using Volo.Abp.Timing;

namespace CKY.AgentPlatform.Application.Performance
{
    /// <summary>
    /// API性能监控和优化服务
    /// 提供API性能监控、缓存策略、限流等功能
    /// </summary>
    public class ApiPerformanceService : ITransientDependency
    {
        private readonly IMemoryCache _cache;
        private readonly ILogger<ApiPerformanceService> _logger;
        private readonly IClock _clock;

        public ApiPerformanceService(
            IMemoryCache cache,
            ILogger<ApiPerformanceService> logger,
            IClock clock)
        {
            _cache = cache;
            _logger = logger;
            _clock = clock;
        }

        /// <summary>
        /// 记录API调用性能指标
        /// </summary>
        public void RecordApiCall(string apiPath, string method, int statusCode, long responseTimeMs)
        {
            var cacheKey = $"api_performance_{apiPath}_{method}";

            var performanceData = _cache.GetOrCreate(cacheKey, entry =>
            {
                entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);
                return new ApiPerformanceData
                {
                    ApiPath = apiPath,
                    Method = method,
                    CallCount = 0,
                    TotalResponseTime = 0,
                    TotalErrors = 0,
                    LastCalled = _clock.Now,
                    PerformanceHistory = new List<ApiCallRecord>()
                };
            });

            performanceData.CallCount++;
            performanceData.TotalResponseTime += responseTimeMs;
            performanceData.AverageResponseTime = performanceData.TotalResponseTime / performanceData.CallCount;
            performanceData.LastCalled = _clock.Now;

            if (statusCode >= 400)
            {
                performanceData.TotalErrors++;
            }

            // 记录性能历史（保留最近100条）
            performanceData.PerformanceHistory.Add(new ApiCallRecord
            {
                Timestamp = _clock.Now,
                StatusCode = statusCode,
                ResponseTimeMs = responseTimeMs
            });

            if (performanceData.PerformanceHistory.Count > 100)
            {
                performanceData.PerformanceHistory.RemoveAt(0);
            }

            // 检查是否需要告警
            if (responseTimeMs > 1000) // 慢响应告警
            {
                _logger.LogWarning("慢API响应: {ApiPath} {Method} - {ResponseTime}ms", apiPath, method, responseTimeMs);
            }

            if (statusCode >= 500) // 服务器错误告警
            {
                _logger.LogError("API服务器错误: {ApiPath} {Method} - {StatusCode}", apiPath, method, statusCode);
            }
        }

        /// <summary>
        /// 获取API性能统计信息
        /// </summary>
        public async Task<List<ApiPerformanceSummary>> GetApiPerformanceStatsAsync()
        {
            // IMemoryCache不提供直接获取所有键的方法，这里使用反射来获取
            var performanceKeys = new List<string>();
            try
            {
                var cacheEntriesCollection = _cache.GetType().GetProperty("EntriesCollection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                if (cacheEntriesCollection != null)
                {
                    var collection = cacheEntriesCollection.GetValue(_cache) as System.Collections.ICollection;
                    if (collection != null)
                    {
                        foreach (var item in collection)
                        {
                            var keyProperty = item.GetType().GetProperty("Key");
                            if (keyProperty != null)
                            {
                                var key = keyProperty.GetValue(item)?.ToString();
                                if (key != null && key.StartsWith("api_performance_"))
                                {
                                    performanceKeys.Add(key);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "无法获取缓存键集合");
            }

            var performanceStats = new List<ApiPerformanceSummary>();

            foreach (var key in performanceKeys)
            {
                if (_cache.TryGetValue(key, out ApiPerformanceData data))
                {
                    performanceStats.Add(new ApiPerformanceSummary
                    {
                        ApiPath = data.ApiPath,
                        Method = data.Method,
                        CallCount = data.CallCount,
                        AverageResponseTime = data.AverageResponseTime,
                        ErrorRate = data.CallCount > 0 ? (data.TotalErrors * 100.0 / data.CallCount) : 0,
                        LastCalled = data.LastCalled,
                        P95ResponseTime = CalculateP95ResponseTime(data.PerformanceHistory),
                        P99ResponseTime = CalculateP99ResponseTime(data.PerformanceHistory)
                    });
                }
            }

            return performanceStats.OrderByDescending(s => s.AverageResponseTime).ToList();
        }

        /// <summary>
        /// 获取API性能趋势
        /// </summary>
        public async Task<ApiPerformanceTrend> GetPerformanceTrendAsync(string apiPath, string method, TimeSpan timeRange)
        {
            var cacheKey = $"api_performance_{apiPath}_{method}";

            if (!_cache.TryGetValue(cacheKey, out ApiPerformanceData data))
            {
                return new ApiPerformanceTrend
                {
                    ApiPath = apiPath,
                    Method = method,
                    TrendPoints = new List<PerformanceTrendPoint>()
                };
            }

            var trendPoints = data.PerformanceHistory
                .Where(h => _clock.Now - h.Timestamp <= timeRange)
                .GroupBy(h => new DateTime(h.Timestamp.Year, h.Timestamp.Month, h.Timestamp.Day, h.Timestamp.Hour, h.Timestamp.Minute / 5 * 5, 0)) // 5分钟间隔
                .Select(g => new PerformanceTrendPoint
                {
                    Timestamp = g.Key,
                    AverageResponseTime = g.Average(r => r.ResponseTimeMs),
                    CallCount = g.Count(),
                    ErrorRate = g.Count(r => r.StatusCode >= 400) * 100.0 / g.Count()
                })
                .OrderBy(p => p.Timestamp)
                .ToList();

            return new ApiPerformanceTrend
            {
                ApiPath = apiPath,
                Method = method,
                TrendPoints = trendPoints
            };
        }

        /// <summary>
        /// 获取API优化建议
        /// </summary>
        public async Task<List<ApiOptimizationRecommendation>> GetOptimizationRecommendationsAsync()
        {
            var performanceStats = await GetApiPerformanceStatsAsync();
            var recommendations = new List<ApiOptimizationRecommendation>();

            foreach (var stat in performanceStats)
            {
                // 慢响应建议
                if (stat.AverageResponseTime > 500)
                {
                    recommendations.Add(new ApiOptimizationRecommendation
                    {
                        Type = "SlowResponse",
                        Severity = "High",
                        ApiPath = stat.ApiPath,
                        Method = stat.Method,
                        Title = "API响应时间过长",
                        Description = $"{stat.ApiPath} 平均响应时间为 {stat.AverageResponseTime}ms",
                        Recommendation = "优化数据库查询，添加缓存，考虑异步处理",
                        Impact = "High"
                    });
                }

                // 高错误率建议
                if (stat.ErrorRate > 5)
                {
                    recommendations.Add(new ApiOptimizationRecommendation
                    {
                        Type = "HighErrorRate",
                        Severity = "Critical",
                        ApiPath = stat.ApiPath,
                        Method = stat.Method,
                        Title = "API错误率过高",
                        Description = $"{stat.ApiPath} 错误率为 {stat.ErrorRate}%",
                        Recommendation = "检查错误日志，修复异常处理逻辑",
                        Impact = "Critical"
                    });
                }

                // 高频调用建议
                if (stat.CallCount > 1000)
                {
                    recommendations.Add(new ApiOptimizationRecommendation
                    {
                        Type = "HighFrequency",
                        Severity = "Medium",
                        ApiPath = stat.ApiPath,
                        Method = stat.Method,
                        Title = "API调用频率过高",
                        Description = $"{stat.ApiPath} 在过去1小时内被调用 {stat.CallCount} 次",
                        Recommendation = "考虑实现API限流和缓存策略",
                        Impact = "Medium"
                    });
                }
            }

            return recommendations;
        }

        /// <summary>
        /// 清理API性能缓存
        /// </summary>
        public void ClearPerformanceCache()
        {
            // IMemoryCache不提供直接获取所有键的方法，这里使用反射来获取
            var cacheKeys = new List<string>();
            try
            {
                var cacheEntriesCollection = _cache.GetType().GetProperty("EntriesCollection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                if (cacheEntriesCollection != null)
                {
                    var collection = cacheEntriesCollection.GetValue(_cache) as System.Collections.ICollection;
                    if (collection != null)
                    {
                        foreach (var item in collection)
                        {
                            var keyProperty = item.GetType().GetProperty("Key");
                            if (keyProperty != null)
                            {
                                var key = keyProperty.GetValue(item)?.ToString();
                                if (key != null && key.StartsWith("api_performance_"))
                                {
                                    cacheKeys.Add(key);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "无法获取缓存键集合");
            }

            foreach (var key in cacheKeys)
            {
                _cache.Remove(key);
            }

            _logger.LogInformation($"已清理 {cacheKeys.Count} 个API性能缓存项");
        }

        /// <summary>
        /// 计算P95响应时间
        /// </summary>
        private double CalculateP95ResponseTime(List<ApiCallRecord> records)
        {
            if (records.Count == 0) return 0;

            var sortedTimes = records.Select(r => r.ResponseTimeMs).OrderBy(t => t).ToList();
            var index = (int)Math.Ceiling(95 * sortedTimes.Count / 100.0) - 1;
            return sortedTimes[Math.Max(0, Math.Min(index, sortedTimes.Count - 1))];
        }

        /// <summary>
        /// 计算P99响应时间
        /// </summary>
        private double CalculateP99ResponseTime(List<ApiCallRecord> records)
        {
            if (records.Count == 0) return 0;

            var sortedTimes = records.Select(r => r.ResponseTimeMs).OrderBy(t => t).ToList();
            var index = (int)Math.Ceiling(99 * sortedTimes.Count / 100.0) - 1;
            return sortedTimes[Math.Max(0, Math.Min(index, sortedTimes.Count - 1))];
        }
    }

    /// <summary>
    /// API性能数据
    /// </summary>
    public class ApiPerformanceData
    {
        public string ApiPath { get; set; }
        public string Method { get; set; }
        public int CallCount { get; set; }
        public long TotalResponseTime { get; set; }
        public double AverageResponseTime { get; set; }
        public int TotalErrors { get; set; }
        public DateTime LastCalled { get; set; }
        public List<ApiCallRecord> PerformanceHistory { get; set; }
    }

    /// <summary>
    /// API调用记录
    /// </summary>
    public class ApiCallRecord
    {
        public DateTime Timestamp { get; set; }
        public int StatusCode { get; set; }
        public long ResponseTimeMs { get; set; }
    }

    /// <summary>
    /// API性能摘要
    /// </summary>
    public class ApiPerformanceSummary
    {
        public string ApiPath { get; set; }
        public string Method { get; set; }
        public int CallCount { get; set; }
        public double AverageResponseTime { get; set; }
        public double ErrorRate { get; set; }
        public DateTime LastCalled { get; set; }
        public double P95ResponseTime { get; set; }
        public double P99ResponseTime { get; set; }
    }

    /// <summary>
    /// API性能趋势
    /// </summary>
    public class ApiPerformanceTrend
    {
        public string ApiPath { get; set; }
        public string Method { get; set; }
        public List<PerformanceTrendPoint> TrendPoints { get; set; }
    }

    /// <summary>
    /// 性能趋势点
    /// </summary>
    public class PerformanceTrendPoint
    {
        public DateTime Timestamp { get; set; }
        public double AverageResponseTime { get; set; }
        public int CallCount { get; set; }
        public double ErrorRate { get; set; }
    }

    /// <summary>
    /// API优化建议
    /// </summary>
    public class ApiOptimizationRecommendation
    {
        public string Type { get; set; }
        public string Severity { get; set; }
        public string ApiPath { get; set; }
        public string Method { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public string Recommendation { get; set; }
        public string Impact { get; set; }
    }

    /// <summary>
    /// API性能中间件
    /// </summary>
    public class ApiPerformanceMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ApiPerformanceService _performanceService;

        public ApiPerformanceMiddleware(RequestDelegate next, ApiPerformanceService performanceService)
        {
            _next = next;
            _performanceService = performanceService;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            var stopwatch = System.Diagnostics.Stopwatch.StartNew();
            var startTime = DateTime.UtcNow;

            try
            {
                await _next(context);
            }
            finally
            {
                stopwatch.Stop();
                var responseTime = stopwatch.ElapsedMilliseconds;

                // 记录API性能数据
                var apiPath = context.Request.Path;
                var method = context.Request.Method;
                var statusCode = context.Response.StatusCode;

                _performanceService.RecordApiCall(apiPath, method, statusCode, responseTime);

                // 添加性能响应头
                context.Response.Headers.Add("X-Response-Time", responseTime + "ms");
            }
        }
    }
}